package com.yunhe.policyfulfillment.policyful.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.model.mybatis.PageResult;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.policyfulfillment.authority.domain.PolicyOrg;
import com.yunhe.policyfulfillment.authority.domain.PolicyUser;
import com.yunhe.policyfulfillment.authority.service.IPolicyOrgService;
import com.yunhe.policyfulfillment.constant.PolicyFulfillmentConstant;
import com.yunhe.policyfulfillment.policyful.domain.PolicyInfoApplyMatter;
import com.yunhe.policyfulfillment.policyful.domain.PolicyInfoDeclareMaterial;
import com.yunhe.policyfulfillment.policyful.domain.PolicyInfoMatter;
import com.yunhe.policyfulfillment.policyful.domain.PolicyInfoNews;
import com.yunhe.policyfulfillment.policyful.model.*;
import com.yunhe.policyfulfillment.policyful.repository.IPolicyInfoDeclareMaterialRepository;
import com.yunhe.policyfulfillment.policyful.repository.IPolicyInfoMatterRepository;
import com.yunhe.policyfulfillment.policyful.repository.PolicyInfoApplyMatterRepository;
import com.yunhe.policyfulfillment.policyful.repository.PolicyInfoApproveProcessRepository;
import com.yunhe.policyfulfillment.policyful.service.IPolicyInfoMatterService;
import com.yunhe.policyfulfillment.policyful.service.SerialNumService;
import com.yunhe.policyfulfillment.util.BeansUtil;
import com.yunhe.policyfulfillment.util.MyHeaderUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yunhe.common.util.CollectionUtil;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName PolicyInfoMatterServiceImpl
 * @Description TODO
 * @Author HeTao
 * @Date 2021/7/26 10:47
 * @Version 1.0
 **/
@Service
public class PolicyInfoMatterServiceImpl implements IPolicyInfoMatterService {

    @Autowired
    private IPolicyInfoMatterRepository policyInfoMatterRepository;

    @Autowired
    private MyHeaderUtil myHeaderUtil;

    @Autowired
    private IPolicyInfoDeclareMaterialRepository policyInfoDeclareMaterialRepository;

    @Autowired
    private PolicyInfoApplyMatterRepository policyInfoApplyMatterRepository;

    @Autowired
    private PolicyInfoApproveProcessRepository policyInfoApproveProcessRepository;

    @Autowired
    private SerialNumService serialNumService;

    @Autowired
    private IPolicyOrgService policyOrgService;

    @Override
    public void deletePolicyInfoMatter(long id) {
        policyInfoMatterRepository.deletePolicyInfoMatterByPrimaryKey(id);
        policyInfoDeclareMaterialRepository.deletePolicyInfoDeclareMaterialByMatterId(id);
    }

    @Override
    public PageResult findMatterByCondition(PortalMatterQueryCondition portalMatterQueryCondition) {
        PageResult result = null;

        //todo  逻辑未写
        PolicyInfoMatterQueryCondition policyInfoMatterQueryCondition = new PolicyInfoMatterQueryCondition();
        BeanUtils.copyProperties(portalMatterQueryCondition, policyInfoMatterQueryCondition);
        policyInfoMatterQueryCondition.setIsOnline(PolicyFulfillmentConstant.Online_Type.Online.value());
        PageHelper.startPage(policyInfoMatterQueryCondition.getPage(), policyInfoMatterQueryCondition.getSize());
        List<PolicyInfoMatterVo> policyInfoMatterVos = policyInfoMatterRepository.findPolicyInfoMatterByQueryConditionForPortal(policyInfoMatterQueryCondition);
        if (!CollectionUtil.isEmpty(policyInfoMatterVos)) {
            for (PolicyInfoMatterVo policyInfoMatterVo : policyInfoMatterVos) {
                policyInfoMatterVo.setOrgName(myHeaderUtil.getOrgName(policyInfoMatterVo.getOrgId()));
                if (policyInfoMatterVo.getUpdatePerson() != null){
                    policyInfoMatterVo.setUpdatePersonName(myHeaderUtil.getUserName(policyInfoMatterVo.getUpdatePerson()));
                }
            }
        }
        PageInfo<PolicyInfoMatterVo> pageInfo = new PageInfo<>(policyInfoMatterVos);
        result = new PageResult(policyInfoMatterQueryCondition.getPage(), policyInfoMatterQueryCondition.getSize(), (int) pageInfo.getTotal(), policyInfoMatterVos);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized int createPolicyInfoMatter(PolicyInfoMatter policyInfoMatter) throws ArgumentErrorException, PinyinException {
        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
        if (headerUser == null) {
            throw new ArgumentErrorException("登录信息已失效,请重新登录!");
        }
        policyInfoMatter.setPublishPerson(headerUser.getId());
        policyInfoMatter.setOrgId(headerUser.getOrgId());
        processBeforeSave(policyInfoMatter);
        int count = policyInfoMatterRepository.createPolicyInfoMatterSelective(policyInfoMatter);
        List<PolicyInfoDeclareMaterial> policyInfoDeclareMaterials = policyInfoMatter.getPolicyInfoDeclareMaterials();
        if (!CollectionUtil.isEmpty(policyInfoDeclareMaterials)) {
            for (PolicyInfoDeclareMaterial policyInfoDeclareMaterial : policyInfoDeclareMaterials) {
                policyInfoDeclareMaterial.setMatterId(policyInfoMatter.getId());
            }
        }
        policyInfoDeclareMaterialRepository.batchCreatePolicyInfoDeclareMaterial(policyInfoDeclareMaterials);
        return count;
    }

    private void processBeforeSave(PolicyInfoMatter policyInfoMatter) throws ArgumentErrorException, PinyinException {
        PolicyInfoMatter policyInfoMatter1 = policyInfoMatterRepository.searchPolicyInfoMatterByPrimaryKey(policyInfoMatter.getId());
        if(policyInfoMatter1 == null){
            throw new ArgumentErrorException("对应的事项不存在");
        }
        policyInfoMatter.setOrgId(policyInfoMatter1.getOrgId());
        //校验编号是否重复
        PolicyOrg policyOrg = policyOrgService.findPolicyOrgByOrgId(policyInfoMatter.getOrgId());
        if (policyOrg == null) {
            throw new ArgumentErrorException("对应主管部门不存在！");
        }
        if(policyInfoMatter.getId() == null){
            String s = PinyinHelper.getShortPinyin(policyOrg.getOrgName()).toUpperCase();
            String matterCode = serialNumService.generateSerialNumberByModelCode("MATTER");
            policyInfoMatter.setCode(s+matterCode);
        }
        PolicyInfoMatter policyInfoMatterByCode = policyInfoMatterRepository.searchPolicyInfoMatterByCode(policyInfoMatter.getCode());
        if (policyInfoMatterByCode != null ) {
            if(policyInfoMatter.getId() == null ||  policyInfoMatterByCode.getId().longValue() != policyInfoMatter.getId().longValue()){
                throw new ArgumentErrorException("事项编号" + policyInfoMatter.getCode() + "已经存在!");
            }
        }
        long currentTimeMillis = System.currentTimeMillis();
        if (policyInfoMatter.getPublishTime() == null) {
            policyInfoMatter.setIsOnline(PolicyFulfillmentConstant.Online_Type.Online.value());
            policyInfoMatter.setPublishTime(new Date());
        } else {
            if (policyInfoMatter.getPublishTime().getTime() <= currentTimeMillis) {
                policyInfoMatter.setIsOnline(PolicyFulfillmentConstant.Online_Type.Online.value());
            }
        }
        //校验当前时间是否已经在申报中
        if (policyInfoMatter.getDeclareStartTime().getTime() > currentTimeMillis) {
            policyInfoMatter.setMatterStatus(PolicyFulfillmentConstant.Declare_Type.NoStart.value());
        } else if (policyInfoMatter.getDeclareStartTime().getTime() <= currentTimeMillis
                && policyInfoMatter.getDeclareEndTime().getTime() <= currentTimeMillis) {
            policyInfoMatter.setMatterStatus(PolicyFulfillmentConstant.Declare_Type.HasEnded.value());
        } else {
            policyInfoMatter.setMatterStatus(PolicyFulfillmentConstant.Declare_Type.Declaring.value());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePolicyInfoMatter(PolicyInfoMatter policyInfoMatter) throws ArgumentErrorException, PinyinException {
        processBeforeSave(policyInfoMatter);
        if (myHeaderUtil.getHeaderUser() != null){
            policyInfoMatter.setUpdatePerson(myHeaderUtil.getHeaderUserId());
        }
        int count = policyInfoMatterRepository.updatePolicyInfoMatterByPrimaryKeySelective(policyInfoMatter);
        policyInfoDeclareMaterialRepository.deletePolicyInfoDeclareMaterialByMatterId(policyInfoMatter.getId());
        List<PolicyInfoDeclareMaterial> policyInfoDeclareMaterials = policyInfoMatter.getPolicyInfoDeclareMaterials();
        if (!CollectionUtil.isEmpty(policyInfoDeclareMaterials)) {
            for (PolicyInfoDeclareMaterial policyInfoDeclareMaterial : policyInfoDeclareMaterials) {
                policyInfoDeclareMaterial.setMatterId(policyInfoMatter.getId());
            }
        }
        policyInfoDeclareMaterialRepository.batchCreatePolicyInfoDeclareMaterial(policyInfoDeclareMaterials);
        return count;
    }

    @Override
    public PolicyInfoMatter findPolicyInfoMatterById(long id) {
        PolicyInfoMatter policyInfoMatter = policyInfoMatterRepository.searchPolicyInfoMatterByPrimaryKey(id);
        List<PolicyInfoDeclareMaterial> policyInfoDeclareMaterials = policyInfoDeclareMaterialRepository.searchPolicyInfoDeclareMaterialByMatterId(id);
        if (policyInfoMatter != null) {
            policyInfoMatter.setPublishPersonName(myHeaderUtil.getUserName(policyInfoMatter.getPublishPerson()));
            policyInfoMatter.setOrgName(myHeaderUtil.getOrgName(policyInfoMatter.getOrgId()));
            if (policyInfoMatter.getUpdatePerson() != null) {
                policyInfoMatter.setUpdatePersonName(myHeaderUtil.getUserName(policyInfoMatter.getUpdatePerson()));
            }
        }
        policyInfoMatter.setPolicyInfoDeclareMaterials(policyInfoDeclareMaterials);
        return policyInfoMatter;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setPublishStatus(PublishStatus publishStatus) {
        List<Long> ids = publishStatus.getIds();
        if (!CollectionUtil.isEmpty(ids)) {
            for (Long id : ids) {
                PolicyInfoMatter policyInfoMatter = new PolicyInfoMatter();
                policyInfoMatter.setId(id);
                policyInfoMatter.setUpdateTime(new Date());
                policyInfoMatter.setIsOnline(publishStatus.getPublishStatus());
                if (myHeaderUtil.getHeaderUser() != null) {
                    policyInfoMatter.setUpdatePerson(myHeaderUtil.getHeaderUserId());
                }
                if (PolicyFulfillmentConstant.Online_Type.Online.value().equals(publishStatus.getPublishStatus())) {
                    policyInfoMatter.setPublishTime(new Date());
                }
                policyInfoMatter.setAccessCount(null);
                policyInfoMatter.setDeclaredQuantity(null);
                policyInfoMatterRepository.updatePolicyInfoMatterByPrimaryKeySelective(policyInfoMatter);
            }
        }
    }

    @Override
    public PageResult findPolicyInfoMatterByQueryCondition(PolicyInfoMatterQueryCondition policyInfoMatterQueryCondition) throws ArgumentErrorException {
        PageResult result = null;
//        PolicyUser headerUser = myHeaderUtil.getHeaderUser();
//        if(headerUser == null){
//            throw new ArgumentErrorException("登录信息已失效,请重新登录!");
//        }
//        policyInfoMatterQueryCondition.setPublishPerson(headerUser.getId());
//        policyInfoMatterQueryCondition.setOrgId(headerUser.getOrgId());
        PageHelper.startPage(policyInfoMatterQueryCondition.getPage(), policyInfoMatterQueryCondition.getSize());
        List<PolicyInfoMatterVo> policyInfoMatterVos = policyInfoMatterRepository.findPolicyInfoMatterByQueryCondition(policyInfoMatterQueryCondition);
        if (!CollectionUtil.isEmpty(policyInfoMatterVos)) {
            for (PolicyInfoMatterVo policyInfoMatterVo : policyInfoMatterVos) {
                policyInfoMatterVo.setPublishPersonName(myHeaderUtil.getUserName(policyInfoMatterVo.getPublishPerson()));
                policyInfoMatterVo.setOrgName(myHeaderUtil.getOrgName(policyInfoMatterVo.getOrgId()));
                if (policyInfoMatterVo.getUpdatePerson()!= null){
                    policyInfoMatterVo.setUpdatePersonName(myHeaderUtil.getUserName(policyInfoMatterVo.getUpdatePerson()));
                }
                String startTime = DateTimeUtils.format(DateTimeUtils.PATTERN.DATE.value(), policyInfoMatterVo.getDeclareStartTime());
                String endTime = DateTimeUtils.format(DateTimeUtils.PATTERN.DATE.value(), policyInfoMatterVo.getDeclareEndTime());
                policyInfoMatterVo.setValidityPeriod(startTime+"~"+endTime);
                //查询该事项的申请企业数，以及已经拨付的数量
                List<PolicyInfoApplyMatter> policyInfoApplyMatters = policyInfoApplyMatterRepository.searchPolicyInfoApplyMatterByApplyMatterId(policyInfoMatterVo.getId());
                if(!CollectionUtil.isEmpty(policyInfoApplyMatters)){
                    policyInfoMatterVo.setCurrentDeclareCount(policyInfoApplyMatters.size());
                    List<PolicyInfoApplyMatter> policyInfoApplyMatterList = policyInfoApplyMatters.stream().filter(policyInfoApplyMatter -> {
                        return policyInfoApplyMatter.getCurrentAuditNode().equals(PolicyFulfillmentConstant.Matter_Audit_Node.Disbursed.value());
                    }).collect(Collectors.toList());
                    if(!CollectionUtil.isEmpty(policyInfoApplyMatterList)){
                        policyInfoMatterVo.setGrantEnterpriseCount(policyInfoApplyMatterList.size());
                    }
                }
            }
            PageInfo<PolicyInfoMatterVo> pageInfo = new PageInfo<>(policyInfoMatterVos);
            result = new PageResult(policyInfoMatterQueryCondition.getPage(), policyInfoMatterQueryCondition.getSize(), (int) pageInfo.getTotal(), policyInfoMatterVos);
        }
        return result;
    }

    @Override
    public MatterStatisticsVo getMatterStatistics() {
        MatterStatisticsVo matterStatisticsVo = new MatterStatisticsVo();
        int onlineMatterCount = policyInfoMatterRepository.getOnlineMatterCount();
        int declaringMatterCount = policyInfoMatterRepository.getDeclaringMatterCount();
        long totalAccessCount = policyInfoMatterRepository.getTotalMatterAccessCount();
        long declaredQuantity = policyInfoMatterRepository.getDeclaredQuantity();
        matterStatisticsVo.setOnlineMatterCount(onlineMatterCount);
        matterStatisticsVo.setDeclaringMatterCount(declaringMatterCount);
        matterStatisticsVo.setTotalAccessCount(totalAccessCount);
        matterStatisticsVo.setDeclaredQuantity(declaredQuantity);
        return matterStatisticsVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void updateMatterAccessCountById(long id) {
        PolicyInfoMatter policyInfoMatter = policyInfoMatterRepository.searchPolicyInfoMatterByPrimaryKey(id);
        policyInfoMatterRepository.updateMatterAccessCountById(id, policyInfoMatter.getAccessCount() + 1);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishTimedMatter() {
        policyInfoMatterRepository.publishTimedMatter();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishTimedUpdateMatterStatus() {
        policyInfoMatterRepository.updateMatterDeclaringStatus();
        policyInfoMatterRepository.updateMatterHasEndedStatus();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void updateMatterDeclaredQuantityById(long applyMatterId) {
        PolicyInfoMatter policyInfoMatter = policyInfoMatterRepository.searchPolicyInfoMatterByPrimaryKey(applyMatterId);
        policyInfoMatterRepository.updateMatterDeclaredQuantityById(applyMatterId, policyInfoMatter.getDeclaredQuantity() + 1);
    }

    @Override
    public List<IndexStatistics> getIndexStatistics() {
        List<IndexStatistics> indexStatisticsList = new ArrayList<>();
        List<String> years = getYearsList();
        for (String year : years) {
            int yearInt = Integer.parseInt(year);
            IndexStatistics indexStatistics = new IndexStatistics();
            indexStatistics.setYear(year);
            //政策事项数量
            Integer policyMatterCount = policyInfoMatterRepository.getPolicyMatterCount(yearInt);
            indexStatistics.setPolicyMatterCount(policyMatterCount == null ? 0 : policyMatterCount);
            //办件量
            Integer workVolume = policyInfoApplyMatterRepository.getWorkVolume(yearInt);
            indexStatistics.setWorkVolume(workVolume == null ? 0 :workVolume);
            //奖励企业数
            Integer awardedEnterprisesCount = policyInfoApplyMatterRepository.getAwardedEnterprisesCount(yearInt);
            indexStatistics.setAwardedEnterprisesCount(awardedEnterprisesCount == null ? 0 :awardedEnterprisesCount);
            //奖励金额(万元)
            Long rewardAmount = policyInfoApproveProcessRepository.getRewardAmount(yearInt);
            if (rewardAmount == null){
                indexStatistics.setRewardAmount(0.0);
            }else {
                BigDecimal rewardAmountBd = new BigDecimal(rewardAmount);
                BigDecimal wan = new BigDecimal(10000);
                double rewardAmountDouble = rewardAmountBd.divide(wan).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                indexStatistics.setRewardAmount(rewardAmountDouble);
            }

            indexStatisticsList.add(indexStatistics);
        }
        return indexStatisticsList;
    }

    @Override
    public PageResult findPolicyInfoMatterByQueryConditionForPortal(PolicyInfoMatterQueryCondition policyInfoMatterQueryCondition) {
        PageResult result = null;
        PageHelper.startPage(policyInfoMatterQueryCondition.getPage(), policyInfoMatterQueryCondition.getSize());
        List<PolicyInfoMatterVo> policyInfoMatterVos = policyInfoMatterRepository.findPolicyInfoMatterByQueryConditionForPortal(policyInfoMatterQueryCondition);
        if (!CollectionUtil.isEmpty(policyInfoMatterVos)) {
            for (PolicyInfoMatterVo policyInfoMatterVo : policyInfoMatterVos) {
                policyInfoMatterVo.setPublishPersonName(myHeaderUtil.getUserName(policyInfoMatterVo.getPublishPerson()));
                policyInfoMatterVo.setOrgName(myHeaderUtil.getOrgName(policyInfoMatterVo.getOrgId()));
                if (policyInfoMatterVo.getUpdatePerson()!= null){
                    policyInfoMatterVo.setUpdatePersonName(myHeaderUtil.getUserName(policyInfoMatterVo.getUpdatePerson()));
                }
                String startTime = DateTimeUtils.format(DateTimeUtils.PATTERN.DATE.value(), policyInfoMatterVo.getDeclareStartTime());
                String endTime = DateTimeUtils.format(DateTimeUtils.PATTERN.DATE.value(), policyInfoMatterVo.getDeclareEndTime());
                policyInfoMatterVo.setValidityPeriod(startTime+"~"+endTime);
                //查询该事项的申请企业数，以及已经拨付的数量
                List<PolicyInfoApplyMatter> policyInfoApplyMatters = policyInfoApplyMatterRepository.searchPolicyInfoApplyMatterByApplyMatterId(policyInfoMatterVo.getId());
                if(!CollectionUtil.isEmpty(policyInfoApplyMatters)){
                    policyInfoMatterVo.setCurrentDeclareCount(policyInfoApplyMatters.size());
                    List<PolicyInfoApplyMatter> policyInfoApplyMatterList = policyInfoApplyMatters.stream().filter(policyInfoApplyMatter -> {
                        return policyInfoApplyMatter.getCurrentAuditNode().equals(PolicyFulfillmentConstant.Matter_Audit_Node.Disbursed.value());
                    }).collect(Collectors.toList());
                    if(!CollectionUtil.isEmpty(policyInfoApplyMatterList)){
                        policyInfoMatterVo.setGrantEnterpriseCount(policyInfoApplyMatterList.size());
                    }
                }
            }
            PageInfo<PolicyInfoMatterVo> pageInfo = new PageInfo<>(policyInfoMatterVos);
            result = new PageResult(policyInfoMatterQueryCondition.getPage(), policyInfoMatterQueryCondition.getSize(), (int) pageInfo.getTotal(), policyInfoMatterVos);
        }
        return result;
    }

    public List<String> getYearsList(){
        List<String> years = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        Date now = new Date();
        cal.setTime(now);
        int yearInt = cal.get(Calendar.YEAR);
        int lastYearInt = yearInt - 1;
        years.add(String.valueOf(lastYearInt));
        years.add(String.valueOf(yearInt));
        return years;
    }
}
